__author__ = 'Berendeeva'

from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.keys import Keys
import time


class Session():
    """
    This class starts a browser and closes its.
    """

    def __init__(self):
        """
        Initiates a set of given attributes.
        """
        pass

    def open_firefox(self):
        """
        Opens Mozilla Firefox.
        """
        return webdriver.Firefox()

    def open_chrome(self):
        """
        Opens Google Chrome.
        """
        #return webdriver.Chrome()
        return webdriver.Chrome('C:\\Users\\user\\chromedriver.exe')

    def open_explorer(self):
        """
        Opens Internet Explorer.
        """
        caps = DesiredCapabilities.INTERNETEXPLORER
        caps['ignoreProtectedModeSettings'] = True
        caps['ignoreZoomSetting'] = True
        return webdriver.Ie(capabilities=caps)

    def close_browser(self, driver):
        """
        Closes the browser.
        """
        driver.quit()


class Login():
    """
    This class implements login.
    """
    FIELD_USERNAME = "//input[@name='username']"
    FIELD_PASSWORD = "//input[@name='password']"
    BUTTON_SUBMIT = "//input[@type='submit']"

    def __init__(self, driver, url):
        """
        Initiates basic parameters.
        """
        self.driver = driver
        self.driver.get(url)
        self.driver.implicitly_wait(3)

    def login(self, username, password):
        """
        This method logs in with given credentials.
        """
        self.driver.find_element_by_xpath(self.FIELD_USERNAME).clear()
        self.driver.find_element_by_xpath(self.FIELD_USERNAME).send_keys(username)
        self.driver.find_element_by_xpath(self.FIELD_PASSWORD).clear()
        self.driver.find_element_by_xpath(self.FIELD_PASSWORD).send_keys(password)
        self.driver.find_element_by_xpath(self.BUTTON_SUBMIT).click()
        self.driver.implicitly_wait(5)


class Movie():
    """
    This class emulates actions with a movie.
    """

    BUTTON_ADD_MOVIE = "//img[@title='Add movie']"
    BUTTON_SAVE = "//input[@id='submit']"
    FIELD_TITLE = "//input[@name='name']"
    FIELD_YEAR = "//input[@name='year']"
    FIELD_IMDB_NUMBER = "//input[@name='imdbid']"
    FIELD_ALSO_KNOWN_AS = "//textarea[@name='aka']"
    FIELD_DURATION = "//input[@name='duration']"
    FIELD_RATING = "//input[@name='rating']"
    FIELD_FORMAT = "//input[@name='format']"
    BOX_I_OWN_THIS_MOVIE = dict(yes="//input[@id='own_yes']", no="//input[@id='own_no']")
    BOX_I_HAVE_SEEN_THIS_MOVIE = dict(yes="//input[@id='seen_yes']", no="//input[@id='seen_no']")
    BOX_LOANED_OUT = dict(yes="//input[@id='loaned_yes']", no="//input[@id='loaned_no']")
    FIELD_TRAILER_URL = "//input[@name='trailer']"
    FIELD_PERSONAL_NOTES = "//*[@name='notes']"
    FIELD_TAGLINES = "//*[@name='taglines']"
    FIELD_PLOT_OUTLINE = "//*[@name='plotoutline']"
    FIELD_PLOTS = "//*[@name='plots']"
    FIELD_LANGUAGES = "//*[@name='languages']"
    FIELD_SUBTITLES = "//*[@name='subtitles']"
    FIELD_AUDIO = "//*[@name='audio']"
    FIELD_VIDEO = "//*[@name='video']"
    FIELD_COUNTRY = "//*[@name='country']"
    FIELD_GENRES = "//*[@name='genres']"
    FIELD_DIRECTOR = "//*[@name='director']"
    FIELD_WRITER = "//*[@name='writer']"
    FIELD_PRODUCER = "//*[@name='producer']"
    FIELD_MUSIC = "//*[@name='music']"
    FIELD_CAST = "//*[@name='cast']"
    CHOOSER_COVER = "//input[@id='cover']"
    MOVIE_TITLE = "//div[@class='title']"
    BUTTON_REMOVE = "//img[@title='Remove']"
    TEXT = 'This field is required'
    ERROR_TEXT_LABEL = "//*[@class='error']"
    FIELD_SEARCH_FOR_MOVIES = "//input[@id='q']"
    TEXT_SEARCH_RESULTS = 'No movies where found.'
    TEXT_SEARCH_RESULTS_LOCATOR = "//*[@class='content']"

    def __init__(self, driver):
        """
        Initiates basic parameters.
        """
        self.driver = driver

    def add_movie(self, title, year, **qwards):
        """
        This method adds a new movie.
        """
        params = dict()
        self.driver.find_element_by_xpath(self.BUTTON_ADD_MOVIE).click()
        self.driver.find_element_by_xpath(self.FIELD_TITLE).send_keys(title)
        self.driver.find_element_by_xpath(self.FIELD_YEAR).send_keys(year)
        for k, v in qwards.items():
            params.__setitem__(k, v)
        if len(params):
            self.set_additional_params_of_movie(self, params)
        self.driver.find_element_by_xpath(self.BUTTON_SAVE).click()
        self.driver.implicitly_wait(3)

    def check_text_without_filling_required_fields(self, title=None, year=None):
        """
        This method checks that text appears in absence of filling of required fields.
        """
        self.driver.find_element_by_xpath(self.BUTTON_ADD_MOVIE).click()
        if isinstance(type(title), type('')):
            self.driver.find_element_by_xpath(self.FIELD_TITLE).send_keys(title)
        if isinstance(type(year), type('')):
            self.driver.find_element_by_xpath(self.FIELD_YEAR).send_keys(year)
        self.driver.find_element_by_xpath(self.BUTTON_SAVE).click()
        page_text = self.driver.find_element_by_xpath(self.ERROR_TEXT_LABEL).text
        assert page_text.__eq__(self.TEXT)

    @staticmethod
    def set_additional_params_of_movie(self, params):
        """
        This method fills additional fields of description, which aren't required.
        """
        if params.__contains__('imdb_number'):
            self.driver.find_element_by_xpath(self.FIELD_IMDB_NUMBER).send_keys(params['imdb_number'])
        if params.__contains__('also_known_as'):
            self.driver.find_element_by_xpath(self.FIELD_ALSO_KNOWN_AS).send_keys(params['also_known_as'])
        if params.__contains__('duration(minutes)'):
            self.driver.find_element_by_xpath(self.FIELD_DURATION).send_keys(params['duration(minutes)'])
        if params.__contains__('rating'):
            self.driver.find_element_by_xpath(self.FIELD_RATING).send_keys(params['rating'])
        if params.__contains__('format'):
            self.driver.find_element_by_xpath(self.FIELD_FORMAT).clear()
            self.driver.find_element_by_xpath(self.FIELD_FORMAT).send_keys(params['format'])
        if params.__contains__('i_own_this_movie'):
            if params['i_own_this_movie'].__eq__('yes'):
                self.driver.find_element_by_xpath(self.BOX_I_OWN_THIS_MOVIE['yes']).click()
            elif params['i_own_this_movie'].__eq__('no'):
                self.driver.find_element_by_xpath(self.BOX_I_OWN_THIS_MOVIE['no']).click()
        if params.__contains__('i_have_seen_this_movie'):
            if params['i_have_seen_this_movie'].__eq__('yes'):
                self.driver.find_element_by_xpath(self.BOX_I_HAVE_SEEN_THIS_MOVIE['yes']).click()
            elif params['i_have_seen_this_movie'].__eq__('no'):
                self.driver.find_element_by_xpath(self.BOX_I_HAVE_SEEN_THIS_MOVIE['no']).click()
        if params.__contains__('loaned_out'):
            if params['loaned_out'].__eq__('yes'):
                self.driver.find_element_by_xpath(self.BOX_LOANED_OUT['yes']).click()
            elif params['loaned_out'].__eq__('no'):
                self.driver.find_element_by_xpath(self.BOX_LOANED_OUT['no']).click()
        if params.__contains__('trailer_url'):
            self.driver.find_element_by_xpath(self.FIELD_TRAILER_URL).send_keys(params['trailer_url'])
        if params.__contains__('personal_notes'):
            self.driver.find_element_by_xpath(self.FIELD_PERSONAL_NOTES).send_keys(params['personal_notes'])
        if params.__contains__('taglines'):
            self.driver.find_element_by_xpath(self.FIELD_TAGLINES).send_keys(params['taglines'])
        if params.__contains__('plot_outline'):
            self.driver.find_element_by_xpath(self.FIELD_PLOT_OUTLINE).send_keys(params['plot_outline'])
        if params.__contains__('plots'):
            self.driver.find_element_by_xpath(self.FIELD_PLOTS).send_keys(params['plots'])
        if params.__contains__('languages'):
            self.driver.find_element_by_xpath(self.FIELD_LANGUAGES).send_keys(params['languages'])
        if params.__contains__('subtitles'):
            self.driver.find_element_by_xpath(self.FIELD_SUBTITLES).send_keys(params['subtitles'])
        if params.__contains__('audio'):
            self.driver.find_element_by_xpath(self.FIELD_AUDIO).send_keys(params['audio'])
        if params.__contains__('video'):
            self.driver.find_element_by_xpath(self.FIELD_VIDEO).send_keys(params['video'])
        if params.__contains__('country'):
            self.driver.find_element_by_xpath(self.FIELD_COUNTRY).send_keys(params['country'])
        if params.__contains__('genres'):
            self.driver.find_element_by_xpath(self.FIELD_GENRES).send_keys(params['genres'])
        if params.__contains__('director'):
            self.driver.find_element_by_xpath(self.FIELD_DIRECTOR).send_keys(params['director'])
        if params.__contains__('writer'):
            self.driver.find_element_by_xpath(self.FIELD_WRITER).send_keys(params['writer'])
        if params.__contains__('producer'):
            self.driver.find_element_by_xpath(self.FIELD_PRODUCER).send_keys(params['producer'])
        if params.__contains__('music'):
            self.driver.find_element_by_xpath(self.FIELD_MUSIC).send_keys(params['music'])
        if params.__contains__('cast'):
            self.driver.find_element_by_xpath(self.FIELD_CAST).send_keys(params['cast'])
        if params.__contains__('cover'):
            self.driver.find_element_by_xpath(self.CHOOSER_COVER).send_keys(params['cover'])

    def delete_movie(self):
        """
        Deletes a random movie.
        """
        try:
            self.driver.find_element_by_xpath(self.MOVIE_TITLE).click()
        except Exception:
            self.add_movie(title='Test title', year='1999')
        self.driver.find_element_by_xpath(self.BUTTON_REMOVE).click()
        alert = self.driver.switch_to_alert()
        alert.accept()
        self.driver.implicitly_wait(3)

    def find_movie(self, keyword):
        """
        Looks for movies corresponding to given keyword.
        """
        el = self.driver.find_element_by_xpath(self.FIELD_SEARCH_FOR_MOVIES)
        el.send_keys(keyword)
        time.sleep(1)
        el.send_keys(Keys.RETURN)
        self.driver.implicitly_wait(5)
        try:
            el = self.driver.find_element_by_xpath(self.MOVIE_TITLE)
            assert el.text.__contains__(keyword)
        except Exception:
            assert self.TEXT_SEARCH_RESULTS.__eq__(self.driver.find_element_by_xpath(self.TEXT_SEARCH_RESULTS_LOCATOR).text)


















